package net.sudot.chess.business.controller.admin.system;

import net.sudot.chess.business.controller.AbstractBaseController;
import net.sudot.chess.business.dto.EnumDTO;
import net.sudot.chess.business.model.SystemConfig;
import net.sudot.chess.business.model.enums.SystemConfigType;
import net.sudot.chess.business.service.SystemConfigService;
import net.sudot.chess.business.service.system.SystemConfigProcessStrategy;
import net.sudot.chess.config.ApplicationContextRegister;
import net.sudot.chess.exception.BusinessException;
import net.sudot.commons.json.JsonUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 系统配置
 *
 * @author tangjialin on 2018-03-26.
 */
@RestController
@RequestMapping(value = "/admin/system/configs")
public class SystemConfigController extends AbstractBaseController {

    @Resource
    private SystemConfigService systemConfigService;

    /**
     * 获取所有系统配置
     *
     * @return 返回所有系统配置项
     */
    @GetMapping
    public List<SystemConfig> list() {
        return systemConfigService.findAll();
    }

    /**
     * 获取系统配置类型候选项
     *
     * @return 返回获取系统配置类型候选项
     */
    @GetMapping("/types")
    public List<EnumDTO> types() {
        SystemConfigType[] values = SystemConfigType.values();
        List<EnumDTO> enumDTOList = new ArrayList<>(values.length);
        for (SystemConfigType systemConfigType : values) {
            enumDTOList.add(new EnumDTO(systemConfigType.ordinal(), systemConfigType.name(), systemConfigType.remark()));
        }
        return enumDTOList;
    }

    /**
     * 获取配置项的候选项
     *
     * @param attributeKey 配置项键
     * @return 返回配置项的候选项
     */
    @GetMapping("/options")
    public List<EnumDTO> options(String attributeKey) {
        Assert.hasLength(attributeKey, "attributeKey不能为空");
        return systemConfigService.getOptions(attributeKey);
    }

    /**
     * 更新单项系统配置
     *
     * @param config 系统配置
     * @return 返回操作结果
     */
    @PutMapping
    @ResponseStatus(code = HttpStatus.NO_CONTENT)
    public void update(@RequestBody SystemConfig config) {
        SystemConfigType attributeSystemConfigType = config.getAttributeType();
        String attributeKey = config.getAttributeKey();
        String attributeValue = config.getAttributeValue();

        if (attributeSystemConfigType == null || StringUtils.isEmpty(attributeKey) || attributeValue == null) {
            throw new IllegalArgumentException("参数错误");
        }
        if (attributeSystemConfigType == SystemConfigType.DATE && StringUtils.isEmpty(attributeValue)) {
            throw new IllegalArgumentException("日期类型的值不能为空");
        }
        SystemConfig systemConfig = systemConfigService.find(attributeKey);
        Assert.notNull(systemConfig, "配置不存在");
        SystemConfigProcessStrategy configProcessStrategy = ApplicationContextRegister.getApplicationContext().getBean(attributeSystemConfigType.strategy());
        String value = configProcessStrategy.process(systemConfig, attributeValue);
        systemConfig.setAttributeValue(StringUtils.trimToNull(value));
        systemConfig.setMemo(config.getMemo());
        systemConfigService.saveOrUpdate(systemConfig);
    }

    /**
     * 保存单项系统配置
     *
     * @param request HttpServletRequest
     * @return 返回操作结果
     */
    @PostMapping("/upload")
    @ResponseStatus(code = HttpStatus.NO_CONTENT)
    public void upload(HttpServletRequest request) {
        Assert.isTrue(request instanceof MultipartHttpServletRequest, "上传文件不能为空");
        MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartHttpServletRequest.getFileMap();
        Assert.notEmpty(fileMap, "上传文件不能为空");

        Map.Entry<String, MultipartFile> fileEntry = fileMap.entrySet().iterator().next();
        MultipartFile multipartFile = fileEntry.getValue();
        File tempFile = new File(FileUtils.getTempDirectory(), UUID.randomUUID() + "_" + multipartFile.getOriginalFilename());
        try {
            multipartFile.transferTo(tempFile);
        } catch (IOException e) {
            throw new BusinessException("文件上传失败", e);
        }
        String body = multipartHttpServletRequest.getParameter("body");
        SystemConfig systemConfig = JsonUtils.toObject(body, SystemConfig.class);
        Assert.notNull(systemConfig.getAttributeType(), "参数错误");
        SystemConfigProcessStrategy configProcessStrategy = ApplicationContextRegister.getApplicationContext().getBean(SystemConfigType.WECHAT_MEDIA.strategy());
        String value = configProcessStrategy.process(systemConfig, tempFile);
        systemConfig.setAttributeValue(StringUtils.trimToNull(value));
        systemConfig.setAttributeType(SystemConfigType.STRING);
        update(systemConfig);
    }

}
